#include "stdafx.h"
#include "XImageImpl.h"

#include "Util.h"

//////////////////////////////////////////////////////////////////////////

#define CHECK_IMAGE()           \
    if(!NeedImageDraw())        \
        return E_OUTOFMEMORY;

//////////////////////////////////////////////////////////////////////////
template <class I>
CXImageImpl<I>::CXImageImpl()
{
    m_pImageDraw = NULL;
}

template <class I>
CXImageImpl<I>::~CXImageImpl()
{
}

//////////////////////////////////////////////////////////////////////////
// IXImage
template <class I>
HRESULT CXImageImpl<I>::put_Image(IN LPCTSTR szXNC)
{
    CHECK_IMAGE();

    m_strImageXNC = szXNC;

    HRESULT hResult = m_pImageDraw->put_ImagePath(szXNC);
    AutoSizeImpl(FALSE);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_Image(IN XIMAGE xImage)
{
    CHECK_IMAGE();

    m_strImageXNC = _T("");

    HRESULT hResult = m_pImageDraw->put_Image(xImage);
    AutoSizeImpl(FALSE);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_Icon(IN LPCTSTR szXNC, BOOL bBig)
{
    CHECK_IMAGE();

    m_strImageXNC = szXNC;

    HRESULT hResult = m_pImageDraw->put_Icon(szXNC, bBig);
    AutoSizeImpl(FALSE);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_Icon(IN XICON xIcon, IN BOOL bDestroy)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_Icon(xIcon, bDestroy);
    AutoSizeImpl(FALSE);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImagePath(OUT BSTR* pszXNC)
{
    if(m_pImageDraw == NULL)
        return E_FAIL;

    HRESULT hResult = m_pImageDraw->get_ImagePath(pszXNC);
    return hResult;
}

template <class I>
void CXImageImpl<I>::put_DrawType(IN ImageDrawType type)
{
    if(m_pImageDraw == NULL)
        return;

    m_pImageDraw->put_DrawType(type);
}

template <class I>
HRESULT CXImageImpl<I>::put_DrawParams(IN ImageDrawParams* pParam)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_DrawParams(pParam);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_DrawParams(OUT ImageDrawParams* pParam)
{
    if(m_pImageDraw == NULL)
        return E_FAIL;

    HRESULT hResult = m_pImageDraw->get_DrawParams(pParam);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_ImageIndex(IN INT nHIndex, IN INT nVIndex)
{
    CHECK_IMAGE();

	int nOrgHIndex = 0, nOrgVIndex = 0;
	HRESULT hResult = m_pImageDraw->get_Index(&nOrgHIndex, &nOrgVIndex);
	if(FAILED(hResult) || nOrgHIndex != nHIndex || nOrgVIndex != nVIndex)
	{
		hResult = m_pImageDraw->put_Index(nHIndex, nVIndex);
		Invalidate();
	}
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImageIndex(IN LPINT pnHIndex, IN LPINT pnVIndex)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->get_Index(pnHIndex, pnVIndex);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_ImageSubCount(IN INT nHCount, IN INT nVCount)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_SubCount(nHCount, nVCount);
    AutoSizeImpl(FALSE);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImageSubCount(IN LPINT pnHCount, IN LPINT pnVCount)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->get_SubCount(pnHCount, pnVCount);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_ImageAlphaMode(IN eImageAlphaMode nAlphaMode)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_AlphaMode(nAlphaMode);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImageAlphaMode(OUT eImageAlphaMode* pnAlphaMode)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->get_AlphaMode(pnAlphaMode);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_ImageAlphaValue(IN BYTE byAlphaValue)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_AlphaValue(byAlphaValue);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImageAlphaValue(OUT LPBYTE pbyAlphaValue)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->get_AlphaValue(pbyAlphaValue);
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::put_ImageTransparentColor(IN COLORREF clrTrans)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->put_TransparentColor(clrTrans);
    Invalidate();
    return hResult;
}

template <class I>
HRESULT CXImageImpl<I>::get_ImageTransparentColor(OUT LPCOLORREF pclrTrans)
{
    CHECK_IMAGE();

    HRESULT hResult = m_pImageDraw->get_TransparentColor(pclrTrans);
    return hResult;
}

//////////////////////////////////////////////////////////////////////////
// IXFrame
template <class I>
void CXImageImpl<I>::GetAutoSize(OUT LPSIZE pAutoSize)
{
    if(!NeedImageDraw())
        return;

    HRESULT hResult = m_pImageDraw->get_ImageSize(pAutoSize);
}

template <class I>
void CXImageImpl<I>::Draw(XCANVAS xCanvas, const RECT& rcDraw)
{
    superclass::Draw(xCanvas, rcDraw);

    if(!NeedImageDraw())
        return;

    RECT rcClient = {0};
    get_WindowRect(&rcClient);

    m_pImageDraw->Draw(xCanvas, &rcClient);
}

//////////////////////////////////////////////////////////////////////////
// IXBaseObj

template <class I>
void CXImageImpl<I>::OnFinalRelease()
{
    superclass::OnFinalRelease();
    ReleaseData();
}

//////////////////////////////////////////////////////////////////////////
// CXFrameImpl

template <class I>
void CXImageImpl<I>::OnColorizeEnabled(BOOL bEnabled)
{
    if(m_pImageDraw != NULL)
    {
        m_pImageDraw->EnableColorize(bEnabled);
        Invalidate();
    }
}

template <class I>
void CXImageImpl<I>::OnColorized(int hue, int sat, int light)
{
    if(m_pImageDraw != NULL)
    {
        m_pImageDraw->Colorize(hue, sat, light);
        Invalidate();
    }
}

//////////////////////////////////////////////////////////////////////////
// CXImageImpl

template <class I>
void CXImageImpl<I>::ReleaseData()
{
    if(m_pImageDraw != NULL)
        m_pImageDraw->Release();
}

template <class I>
BOOL CXImageImpl<I>::NeedImageDraw()
{
    HRESULT hResult = S_OK;
    if(m_pImageDraw == NULL)
        hResult = Util::CreateObject(&m_pImageDraw);
    XASSERT_ERROR(m_pImageDraw != NULL, _T("ImageDraw Create Failed"));
    return SUCCEEDED(hResult);
}
